using System;
using System.Text.RegularExpressions;
using System.Web.UI;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Administration;
using Microsoft.SharePoint.Utilities;

namespace OrbitOne.SharePoint.Claims.SignIn
{
    public class AutoSignin : Page
    {
        protected override void OnLoad(EventArgs e)
        {
            if (SPContext.Current == null) return;
            if (SPContext.Current.Site == null) return;
            if (SPContext.Current.Site.WebApplication == null) return;

            SPWebApplication app = SPContext.Current.Site.WebApplication;

            SignInConfiguration config = app.GetChild<SignInConfiguration>("SignInConfig");

            SPAlternateUrl u = app.AlternateUrls[Request.Url];
            SPUrlZone zone = u.UrlZone;

            string components = Request.Url.GetComponents(UriComponents.Query, UriFormat.SafeUnescaped);

            SPIisSettings settings = app.IisSettings[zone];

            string ip = IpNetworking.GetIP4Address();
            
            ip = Regex.Replace(ip, @"^(?<Prefix>(\d{1,3}\.){3})\d{1,3}$", "${Prefix}*");

            var signinPageMappings = config.SingInPageMappings;

            if (config != null && config.ProviderMappings.ContainsKey(ip))
            {
                string targetProvider = config.ProviderMappings[ip];
                
                foreach (SPAuthenticationProvider provider in settings.ClaimsAuthenticationProviders)
                {
                    if (string.Compare(provider.DisplayName, targetProvider, true, System.Globalization.CultureInfo.CurrentUICulture) == 0
                        || string.Compare(provider.ClaimProviderName, targetProvider, true, System.Globalization.CultureInfo.CurrentUICulture) == 0)
                    {

                        string url = provider.AuthenticationRedirectionUrl.ToString();
                        if(signinPageMappings.ContainsKey(provider.DisplayName))
                        {
                            url = signinPageMappings[provider.DisplayName];
                        }

                        if (provider is SPWindowsAuthenticationProvider)
                        {
                            components = EnsureReturnUrl(components);
                        }

                        SPUtility.Redirect(url, SPRedirectFlags.Default, this.Context, components);
                    }
                }
            }
            else
            {
                string loginPage = "/_forms/default.aspx";
                if(signinPageMappings.ContainsKey("default"))
                {
                    loginPage = signinPageMappings["default"];
                }
                SPUtility.Redirect(loginPage, SPRedirectFlags.Default, this.Context, components);
                Response.Write("No authentication provider is mapped to your request address, or no matching authentication provider could be found.");
            }

            base.OnLoad(e);
        }
        private string EnsureReturnUrl(string queryString)
        {
            if(string.IsNullOrEmpty(queryString))
            {
                queryString = "?";
            }
            if (!queryString.Contains("ReturnUrl="))
            {
                if (!string.IsNullOrEmpty(queryString))
                {
                    queryString = queryString + "&";
                }
                queryString = queryString + "ReturnUrl=/";
            }
            
            return queryString;
        }
    }
}